package com.byd.modules.biz.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.byd.common.utils.DateUtils;
import com.byd.common.utils.PageUtils;
import com.byd.config.ElasticsearchConfig;
import com.byd.modules.biz.entity.CarModelEntity;
import com.byd.modules.biz.entity.SuperviseEntity;
import com.byd.modules.biz.entity.SuperviseREntity;
import com.byd.modules.biz.entity.SuperviseSubEntity;
import com.byd.modules.biz.service.CarModelService;
import com.byd.modules.biz.service.DimensionService;
import com.byd.modules.biz.service.SuperviseService;
import com.google.gson.Gson;

@Service
public class SuperviseServiceImpl implements SuperviseService {
    Logger logger = Logger.getLogger(SuperviseServiceImpl.class);
    @Autowired
    private CarModelService carModelService;
	@Autowired
	private DimensionService dimensionService;
    @Autowired
    ElasticsearchConfig elasticsearchConfig;
    String json = null;
    
    public static void main(String[] args) throws UnknownHostException {
        // on startup AWCgQG4m1caaXKmn3fbu
        Settings settings = Settings.builder().put("cluster.name", "biyadi-test").build();
        // Add transport addresses and do something with the client...
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("101.89.68.208"), 9300));
        GetResponse response = client.prepareGet("byd", "article", "AWCgQG4m1caaXKmn3fbu").setOperationThreaded(false).get();// 线程安全

        System.out.println(response.getSourceAsString());

        /*
         * SearchResponse scrollResp = client.prepareSearch("byd").addSort(FieldSortBuilder.DOC_FIELD_NAME,
         * SortOrder.ASC)
         * // .setScroll(new TimeValue(60000))
         * .setFrom(1).setSize(10).get(); // max of 100 hits will be returned for each scroll
         * // Scroll until no hits are returned
         * for (SearchHit hit : scrollResp.getHits().getHits()) {
         * // Handle the hit...
         * System.out.println(hit.getSourceAsString());
         * }
         */

        // on shutdown

        // client.close();
    }
    public Map<String, String> paramProcess(Map<String, String> params) {
    	if (StringUtils.isNotBlank(params.get("post_time"))) {
    		String val=params.get("post_time");
    		if (val.equals("7天")) {
    			params.put("post_time", DateUtils.dateCalculationsByDay(new Date(), -7));
			}else if (val.equals("30天")) {
    			params.put("post_time", DateUtils.dateCalculationsByDay(new Date(), -30));
			}else {
				params.put("post_time", "");
			}
		}
    	if (StringUtils.isNotBlank(params.get("platform"))) {
    		String val=params.get("platform");
    		if (val.equals("汽车之家")) {
    			params.put("platform", "autohome");
			}else if (val.equals("易车")) {
    			params.put("platform", "bitauto");
			}else if (val.equals("新浪汽车")) {
    			params.put("platform", "sinaauto");
			}else if (val.equals("太平洋汽车")) {
    			params.put("platform", "pcauto");
			}else if (val.equals("爱卡汽车")) {
    			params.put("platform", "xcar");
			}else {
				params.put("platform", "");
			}
		}
    	if (StringUtils.isNotBlank(params.get("source"))) {
    		String val=params.get("source");
    		if (val.equals("论坛")) {
    			params.put("source", "bbs");
			}else if (val.equals("口碑")) {
    			params.put("source", "koubei");
			}else {
				params.put("source", "");
			}
		}
    	if (StringUtils.isNotBlank(params.get("selectId"))&&!params.get("selectId").equals("0")) {
            CarModelEntity carModel = carModelService.queryObject(Long.parseLong(params.get("selectId")));
            params.put("bbs_name", carModel.getName());
		}else {
			params.put("bbs_name", "");
		}
    	if (StringUtils.isNotBlank(params.get("selectName"))) {
            params.put("bbs_name", params.get("selectName"));
		}
        return params;
    }
    /**
     * 重载方法
     * 
     * @param params
     * @return
     */
    @Override
    public PageUtils queryList(Map<String, String> params) {
        PageUtils page = null;
    	paramProcess(params);
        List<SuperviseEntity> list = new ArrayList<SuperviseEntity>();
        try {
        	  Client client = elasticsearchConfig.getESClient();
//            MatchPhraseQueryBuilder mpq1 = QueryBuilders.matchPhraseQuery("website", "autohome");
//            RangeQueryBuilder mpq2 = QueryBuilders.rangeQuery("post_time.keyword").gte("2017-12-18");
//            WildcardQueryBuilder mpq1 = QueryBuilders.wildcardQuery("website","*bbs");
            BoolQueryBuilder qb = QueryBuilders.boolQuery();
//            qb.must(mpq1).must(mpq2);

//            if (StringUtils.isNotBlank(params.get("post_time"))) {
//                RangeQueryBuilder mpq = QueryBuilders.rangeQuery("create_date").gte(params.get("post_time"));
//                qb.must(mpq);
//            }
//        	if (StringUtils.isNotBlank(params.get("post_time_from"))&&StringUtils.isNotBlank(params.get("post_time_to"))) {
//    			RangeQueryBuilder mpq = QueryBuilders.rangeQuery("").gte(params.get("post_time_from")).lte(params.get("post_time_to"));
//                qb.must(mpq);create_date
//    		}
            if (StringUtils.isNotBlank(params.get("post_time"))) {
                RangeQueryBuilder mpq = QueryBuilders.rangeQuery("post_time_new").gte(params.get("post_time"));
                qb.must(mpq);
            }
        	if (StringUtils.isNotBlank(params.get("post_time_from"))&&StringUtils.isNotBlank(params.get("post_time_to"))) {
        		
//        		//日期转换并+1
//        		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//        	    Date date = null;
//        	    String postTo=params.get("post_time_to");
//        	    date = format.parse(postTo);
//        	    Calendar c = Calendar.getInstance();  
//                c.setTime(date);  
//                c.add(Calendar.DAY_OF_MONTH, 1); 
//                date = c.getTime();
//                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
//                String endDate = sdf1.format(date);
                
    			RangeQueryBuilder mpq = QueryBuilders.rangeQuery("post_time_new").gte(params.get("post_time_from")).lte(params.get("post_time_to"));
                qb.must(mpq);
    		}
            if (StringUtils.isNotBlank(params.get("platform"))) {
            	WildcardQueryBuilder mpq = QueryBuilders.wildcardQuery("website",params.get("platform")+"*");
                qb.must(mpq);
    		}
            if (StringUtils.isNotBlank(params.get("source"))) {
            	WildcardQueryBuilder mpq = QueryBuilders.wildcardQuery("website","*"+params.get("source"));
                qb.must(mpq);
    		}
            if (StringUtils.isNotBlank(params.get("bbs_name"))) {
//            	MatchPhraseQueryBuilder mpq = QueryBuilders.matchPhraseQuery("bbs_name", params.get("bbs_name"));
            	MatchPhraseQueryBuilder mpq = QueryBuilders.matchPhraseQuery("car_series", params.get("bbs_name"));
                qb.must(mpq);
    		}
            if (StringUtils.isNotBlank(params.get("thread_context"))) {
//            	WildcardQueryBuilder mpq = QueryBuilders.wildcardQuery("thread_context","*"+params.get("thread_context")+"*");
//            	MatchPhraseQueryBuilder mpq = QueryBuilders.matchPhraseQuery("thread_context", params.get("thread_context"));
//            	FuzzyQueryBuilder mpq = QueryBuilders.fuzzyQuery("thread_context",params.get("thread_context"));
//            	QueryStringQueryBuilder mpq=QueryBuilders.queryStringQuery("七月份").field("thread_context");
            	MatchPhraseQueryBuilder mpq = QueryBuilders.matchPhraseQuery("thread_context", params.get("thread_context"));
            	qb.must(mpq);
    		}
            
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(qb);
            
            //设置结果集最大记录数
           UpdateSettingsResponse setRes= client.admin().indices().prepareUpdateSettings(elasticsearchConfig.getIndex())   
            .setSettings(Settings.builder()                     
            .put("index.max_result_window", 100000)
            )
            .get(); 
           
            SearchResponse scrollResp = client.prepareSearch(elasticsearchConfig.getIndex())
                    // .setQuery(QueryBuilders.rangeQuery("post_time.keyword").gte("2016-01-01"))
                    //.addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)
                    .setQuery(qb)
                    .addSort("post_time.keyword", SortOrder.DESC)
                    .addSort("user_id.keyword", SortOrder.DESC)
                    //.setScroll(new TimeValue(60000))
		            .setFrom((Integer.parseInt(params.get("currPage"))-1)*Integer.parseInt(params.get("pageSize")))
		            .setSize(Integer.parseInt(params.get("pageSize")))
		            //.execute().actionGet();
		            .get();
            for (SearchHit hit : scrollResp.getHits().getHits()) {
                SuperviseEntity res = new Gson().fromJson(hit.getSourceAsString(), SuperviseEntity.class);
                res.setId(hit.getId());
            	list.add(res);
            }
//          System.out.println(scrollResp);
            Collections.reverse(list);
            page = new PageUtils(list, (int)scrollResp.getHits().getTotalHits(), Integer.parseInt(params.get("pageSize")), Integer.parseInt(params.get("currPage")));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return page;
    }
   
    /**
     * 重载方法
     * 
     * @param id
     * @return
     */
    @Override
    public SuperviseEntity queryObject(String id) {
        SuperviseEntity res = null;
        try {
            Client client = elasticsearchConfig.getESClient();
            GetResponse response = client.prepareGet(elasticsearchConfig.getIndex(), "article", id).setOperationThreaded(false).get();// 线程安全
            // GetResponse response = client.prepareGet("byd", "article",
            // "AWCgQG4m1caaXKmn3fbu").setOperationThreaded(false).get();// 线程安全
            res = new Gson().fromJson(response.getSourceAsString(), SuperviseEntity.class);
            res.setId(response.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }
    /**
     * 重载方法
     * 
     * @param supervise
     */
    @Override
    public void update(SuperviseREntity supervise) {
    	Client client = elasticsearchConfig.getESClient();
        SuperviseEntity entity = this.queryObject(supervise.getDocid());
        entity.getResult().remove(Integer.parseInt(supervise.getIndex()));
        SuperviseSubEntity superviseSubEntity = new SuperviseSubEntity();
        try {
            BeanUtils.copyProperties(superviseSubEntity, supervise);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        superviseSubEntity.setStatus("1");//是否人工校验:校验后1
        entity.getResult().add(Integer.parseInt(supervise.getIndex()), superviseSubEntity);
        carModelService.upNicknameBySuperviseSub(supervise);
        dimensionService.upDescBySuperviseSub(supervise);
        UpdateResponse response = client.prepareUpdate(elasticsearchConfig.getIndex(), "article", supervise.getDocid()).setDoc(new Gson().toJson(entity, SuperviseEntity.class), XContentType.JSON).get();
    }
	@Override
	public void add(SuperviseREntity supervise) {
		Client client = elasticsearchConfig.getESClient();
        SuperviseEntity entity = this.queryObject(supervise.getDocid());
        SuperviseSubEntity superviseSubEntity = new SuperviseSubEntity();
        try {
            BeanUtils.copyProperties(superviseSubEntity, supervise);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        superviseSubEntity.setStatus("1");//是否人工校验:校验后1
        entity.getResult().add(superviseSubEntity);
        carModelService.upNicknameBySuperviseSub(supervise);
        dimensionService.upDescBySuperviseSub(supervise);
        UpdateResponse response = client.prepareUpdate(elasticsearchConfig.getIndex(), "article", supervise.getDocid()).setDoc(new Gson().toJson(entity, SuperviseEntity.class), XContentType.JSON).get();
	}
	@Override
	public void delete(SuperviseREntity supervise) {
		Client client = elasticsearchConfig.getESClient();
        SuperviseEntity entity = this.queryObject(supervise.getDocid());
        entity.getResult().remove(Integer.parseInt(supervise.getIndex()));
        UpdateResponse response = client.prepareUpdate(elasticsearchConfig.getIndex(), "article", supervise.getDocid()).setDoc(new Gson().toJson(entity, SuperviseEntity.class), XContentType.JSON).get();
	}

}